package com.tianji.learning.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.CacheConstant;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.domain.dto.PointMsgDTO;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.Vo.SignResultVO;
import com.tianji.learning.domain.po.SignRecord;
import com.tianji.learning.mapper.SignRecordMapper;
import com.tianji.learning.service.ISignRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 签到记录表 服务实现类
 * </p>
 *
 * @author niu
 */
@Service
@Slf4j
public class SignRecordServiceImpl extends ServiceImpl<SignRecordMapper, SignRecord> implements ISignRecordService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitMqHelper mqHelper;


    @Override
    public List<Integer> getSignRecords() {
        Long userId = UserContext.getUser();
        String key = getSignRecordKey(userId);
        int day = LocalDateTime.now().getDayOfMonth();
        List<Long> value = redisTemplate.opsForValue().bitField(key,
                BitFieldSubCommands.create(
                        BitFieldSubCommands.BitFieldGet.create(BitFieldSubCommands.BitFieldType.unsigned(day), BitFieldSubCommands.Offset.offset(0)))
        );
        log.info("value:{}",value);
        String bitList = Long.toBinaryString(value.get(0));
        List<Integer> integers = new ArrayList<>();
        for (int i = 0; i < day-bitList.length(); i++) {
            integers.add(0);
        }
        for (int i = 0; i < bitList.length(); i++) {
            integers.add(bitList.charAt(i) == '1' ? 1 : 0);
        }
        return integers;
    }

    @Override
    public SignResultVO sign() {
        Long userId = UserContext.getUser();
        String key = getSignRecordKey(userId);
        int day = LocalDateTime.now().getDayOfMonth();
        Boolean oldValue = redisTemplate.opsForValue().setBit(key, day - 1, true);
        if(oldValue){
            throw new BizIllegalException("不能重复签到");
        }
        List<Long> value = redisTemplate.opsForValue().bitField(key,
                BitFieldSubCommands.create(
                        BitFieldSubCommands.BitFieldGet.create(BitFieldSubCommands.BitFieldType.unsigned(day), BitFieldSubCommands.Offset.offset(0)))
        );
        int days=0;
        Long singRecordList = value.get(0);
        String bitList = Long.toBinaryString(singRecordList);
        for (int i = bitList.length()-1; i >= 0; i--) {
            char bit = bitList.charAt(i);
            if(bit == '1'){
                days++;
            }else {
                break;
            }
        }
        int rewardPoints = 0;
        if(days == 7){
            rewardPoints = 10;
        } else if (days == 14) {
            rewardPoints = 20;
        }else if (days == 28) {
            rewardPoints = 40;
        }
        SignResultVO vo = new SignResultVO();
        vo.setSignDays(days);
        vo.setRewardPoints(rewardPoints);
        // 发mq消息，记录积分
        PointMsgDTO msg = new PointMsgDTO(userId, rewardPoints+1);
        mqHelper.send(MqConstants.Exchange.LEARNING_EXCHANGE, MqConstants.Key.SIGN_IN, msg);
        return vo;
    }
    private String getSignRecordKey(Long userId){
        return CacheConstant.SIGN_RECORD + LocalDateTimeUtil.format(LocalDateTime.now(),"yyyy-MM") + ":" + userId;
    }
}
